package ext.acae2.baseline.web;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import wt.doc.WTDocument;
import wt.fc.ReferenceFactory;
import wt.log4j.LogR;
import wt.part.WTPart;
import wt.util.WTException;
import wt.util.WTMessage;
import wt.util.WTProperties;
import wt.util.WTRuntimeException;
import wt.vc.baseline.ManagedBaseline;
import ext.acae2.baseline.resource.BaselineActionResource;


public class CompareBaselineReport {

    private static final Logger LOGGER = LogR.getLogger(CompareBaselineReport.class.getName());
    private static final String RESOURCE = BaselineActionResource.class.getName();
    
    public static final String KEY_INDEX = "KEY_INDEX";
    public static final String KEY_A_NUMBER = "KEY_A_NUMBER";
    public static final String KEY_A_NAME = "KEY_A_NAME";
    public static final String KEY_A_VERSION = "KEY_A_VERSION";
    public static final String KEY_B_NUMBER = "KEY_B_NUMBER";
    public static final String KEY_B_NAME = "KEY_B_NAME";
    public static final String KEY_B_VERSION = "KEY_B_VERSION";
    public static final String KEY_COMPARE_RESULT = "KEY_COMPARE_RESULT";
    
    public static final String RESULT_SAME = WTMessage.getLocalizedMessage(RESOURCE, BaselineActionResource.SAME);
    public static final String RESULT_DIFF_VERSION = WTMessage.getLocalizedMessage(RESOURCE, BaselineActionResource.DIFF_VERSION);
    public static final String RESULT_ADD = WTMessage.getLocalizedMessage(RESOURCE, BaselineActionResource.ADD);
    public static final String RESULT_REMOVE = WTMessage.getLocalizedMessage(RESOURCE, BaselineActionResource.REMOVE);
    
    
    private static String rmiHost;
	private static String protocol;
	private static String webappName;
	
	static {
		try {
			WTProperties props = WTProperties.getLocalProperties();
			rmiHost = props.getProperty("java.rmi.server.hostname");
			protocol=props.getProperty("wt.webserver.protocol");
			webappName = props.getProperty("wt.webapp.name");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
    
    public static String getCompareResultString(String baselineAOid, String baselineBOid)
            throws WTRuntimeException, WTException {
        LOGGER.debug("> Start getCompareResultString");
        
        ReferenceFactory refFactory = new ReferenceFactory();
        ManagedBaseline baselineA = (ManagedBaseline) refFactory.getReference(baselineAOid).getObject();
        ManagedBaseline baselineB = (ManagedBaseline) refFactory.getReference(baselineBOid).getObject();
        
        List<Map<String, String>> compareList = getCompareResultMap(baselineA, baselineB);
        String result = "";
        for (Map<String, String> row : compareList) {
            result += (row.get(KEY_INDEX) + "~" +
                            row.get(KEY_A_NUMBER) + "~" +
                            row.get(KEY_A_NAME) + "~" + 
                            row.get(KEY_A_VERSION) + "~" +
                            row.get(KEY_B_NUMBER) + "~" +
                            row.get(KEY_B_NAME) + "~" + 
                            row.get(KEY_B_VERSION) + "~" + 
                            row.get(KEY_COMPARE_RESULT) + "|");
        }
        
        if (!"".equalsIgnoreCase(result)) {
            result = result.substring(0, result.length() - 1);
        }
        
        LOGGER.debug("result: " + result);
        LOGGER.debug("> End getCompareResultString");
        return result;
    }
    
    public static List<Map<String, String>> getCompareResultMap(ManagedBaseline baselineA, ManagedBaseline baselineB) 
            throws WTException {
        LOGGER.debug("> Start getCompareResultMap");
        
        List<Map<String, String>> resultList = new ArrayList<Map<String, String>>();
        resultList.addAll(getCompareResultMapPart(baselineA, baselineB));
        resultList.addAll(getCompareResultMapDocument(baselineA, baselineB));
        
        LOGGER.debug("> End getCompareResultMap");
        return resultList;
    }
    
    public static List<Map<String, String>> getCompareResultMapPart(
            ManagedBaseline baselineA, ManagedBaseline baselineB) throws WTException {
        LOGGER.debug("> Start getCompareResultMap");
        
        List<WTPart> partListA = BaselineUtil.getBaselineParts(baselineA);
        List<WTPart> partListB = BaselineUtil.getBaselineParts(baselineB);
        
        Map<String, WTPart> partMapA = new HashMap<String, WTPart>();
        for (WTPart part : partListA) {
            partMapA.put(part.getNumber(), part);
        }
        
        Map<String, WTPart> partMapB = new HashMap<String, WTPart>();
        for (WTPart part : partListB) {
            partMapB.put(part.getNumber(), part);
        }
        
        List<Map<String, String>> resultList = new ArrayList<Map<String, String>>();
        
        int index = 1;
        while (true) {
            for (String aKey : partMapA.keySet()) {
                if (partMapB.containsKey(aKey)) {
                    Map<String, String> compareMap = new HashMap<String, String>();
                    
                    WTPart partA = partMapA.get(aKey);
                    WTPart partB = partMapB.get(aKey);
                    
                    String versionA = partA.getVersionIdentifier().getValue() + "." + partA.getIterationIdentifier().getValue();
                    String versionB = partB.getVersionIdentifier().getValue() + "." + partB.getIterationIdentifier().getValue();
                    
                    compareMap.put(KEY_INDEX, String.valueOf(index));
                    compareMap.put(KEY_A_NUMBER, "<img src='"+protocol+"://"+rmiHost+"/"+webappName+"/netmarkets/images/part.gif'/>" + partA.getNumber());
                    compareMap.put(KEY_A_NAME, partA.getName());
                    compareMap.put(KEY_A_VERSION, versionA);
                    compareMap.put(KEY_B_NUMBER, "<img src='"+protocol+"://"+rmiHost+"/"+webappName+"/netmarkets/images/part.gif'/>" + partB.getNumber());
                    compareMap.put(KEY_B_NAME, partB.getName());
                    compareMap.put(KEY_B_VERSION, versionB);
                    
                    if (versionA.equalsIgnoreCase(versionB)) {
                        compareMap.put(KEY_COMPARE_RESULT, RESULT_SAME);
                    }
                    else {
                        compareMap.put(KEY_COMPARE_RESULT, RESULT_DIFF_VERSION);
                    }
                    
                    resultList.add(compareMap);
                    index++;
                }
                else {
                    Map<String, String> compareMap = new HashMap<String, String>();
                    
                    WTPart partA = partMapA.get(aKey);
                    
                    compareMap.put(KEY_INDEX, String.valueOf(index));
                    compareMap.put(KEY_A_NUMBER, "<img src='"+protocol+"://"+rmiHost+"/"+webappName+"/netmarkets/images/part.gif'/>" +  partA.getNumber());
                    compareMap.put(KEY_A_NAME, partA.getName());
                    compareMap.put(KEY_A_VERSION, 
                            partA.getVersionIdentifier().getValue() 
                            + "." + partA.getIterationIdentifier().getValue());
                    compareMap.put(KEY_B_NUMBER, "/");
                    compareMap.put(KEY_B_NAME, "/");
                    compareMap.put(KEY_B_VERSION, "/");
                    
                    compareMap.put(KEY_COMPARE_RESULT, RESULT_REMOVE);
                    
                    resultList.add(compareMap);
                    index++;
                }
            }

            for (String bKey : partMapB.keySet()) {
                if (!partMapA.containsKey(bKey)) {
                    Map<String, String> compareMap = new HashMap<String, String>();
                    
                    WTPart partB = partMapB.get(bKey);
                    
                    compareMap.put(KEY_INDEX, String.valueOf(index));
                    compareMap.put(KEY_A_NUMBER, "/");
                    compareMap.put(KEY_A_NAME, "/");
                    compareMap.put(KEY_A_VERSION, "/");
                    compareMap.put(KEY_B_NUMBER, "<img src='"+protocol+"://"+rmiHost+"/"+webappName+"/netmarkets/images/part.gif'/>" + partB.getNumber());
                    compareMap.put(KEY_B_NAME, partB.getName());
                    compareMap.put(KEY_B_VERSION, 
                            partB.getVersionIdentifier().getValue() 
                            + "." + partB.getIterationIdentifier().getValue());
                    
                    compareMap.put(KEY_COMPARE_RESULT, RESULT_ADD);
                    
                    resultList.add(compareMap);
                    index++;
                }
            }
            
            break;
        }
        
        LOGGER.debug("> End getCompareResultMap");
        return resultList;
    }
    
    public static List<Map<String, String>> getCompareResultMapDocument(
            ManagedBaseline baselineA, ManagedBaseline baselineB) throws WTException {
        LOGGER.debug("> Start getCompareResultMap");
        
        List<WTDocument> docListA = BaselineUtil.getBaselineDocuments(baselineA);
        List<WTDocument> docListB = BaselineUtil.getBaselineDocuments(baselineB);
        
        Map<String, WTDocument> docMapA = new HashMap<String, WTDocument>();
        for (WTDocument doc : docListA) {
            docMapA.put(doc.getNumber(), doc);
        }
        
        Map<String, WTDocument> docMapB = new HashMap<String, WTDocument>();
        for (WTDocument doc : docListB) {
            docMapB.put(doc.getNumber(), doc);
        }
        
        List<Map<String, String>> resultList = new ArrayList<Map<String, String>>();
        
        int index = 1;
        while (true) {
            for (String aKey : docMapA.keySet()) {
                if (docMapB.containsKey(aKey)) {
                    Map<String, String> compareMap = new HashMap<String, String>();
                    
                    WTDocument docA = docMapA.get(aKey);
                    WTDocument docB = docMapB.get(aKey);
                    
                    String versionA = docA.getVersionIdentifier().getValue() + "." + docA.getIterationIdentifier().getValue();
                    String versionB = docB.getVersionIdentifier().getValue() + "." + docB.getIterationIdentifier().getValue();
                    
                    compareMap.put(KEY_INDEX, String.valueOf(index));
                    compareMap.put(KEY_A_NUMBER, "<img src='"+protocol+"://"+rmiHost+"/"+webappName+"/netmarkets/images/doc_document.gif'/>" + docA.getNumber());
                    compareMap.put(KEY_A_NAME, docA.getName());
                    compareMap.put(KEY_A_VERSION, versionA);
                    compareMap.put(KEY_B_NUMBER, "<img src='"+protocol+"://"+rmiHost+"/"+webappName+"/netmarkets/images/doc_document.gif'/>" + docB.getNumber());
                    compareMap.put(KEY_B_NAME, docB.getName());
                    compareMap.put(KEY_B_VERSION, versionB);
                    
                    if (versionA.equalsIgnoreCase(versionB)) {
                        compareMap.put(KEY_COMPARE_RESULT, RESULT_SAME);
                    }
                    else {
                        compareMap.put(KEY_COMPARE_RESULT, RESULT_DIFF_VERSION);
                    }
                    
                    resultList.add(compareMap);
                    index++;
                }
                else {
                    Map<String, String> compareMap = new HashMap<String, String>();
                    
                    WTDocument docA = docMapA.get(aKey);
                    
                    compareMap.put(KEY_INDEX, String.valueOf(index));
                    compareMap.put(KEY_A_NUMBER, "<img src='"+protocol+"://"+rmiHost+"/"+webappName+"/netmarkets/images/doc_document.gif'/>" + docA.getNumber());
                    compareMap.put(KEY_A_NAME, docA.getName());
                    compareMap.put(KEY_A_VERSION, 
                            docA.getVersionIdentifier().getValue() 
                            + "." + docA.getIterationIdentifier().getValue());
                    compareMap.put(KEY_B_NUMBER, "/");
                    compareMap.put(KEY_B_NAME, "/");
                    compareMap.put(KEY_B_VERSION, "/");
                    
                    compareMap.put(KEY_COMPARE_RESULT, RESULT_REMOVE);
                    
                    resultList.add(compareMap);
                    index++;
                }
            }

            for (String bKey : docMapB.keySet()) {
                if (!docMapA.containsKey(bKey)) {
                    Map<String, String> compareMap = new HashMap<String, String>();
                    
                    WTDocument docB = docMapB.get(bKey);
                    
                    compareMap.put(KEY_INDEX, String.valueOf(index));
                    compareMap.put(KEY_A_NUMBER, "/");
                    compareMap.put(KEY_A_NAME, "/");
                    compareMap.put(KEY_A_VERSION, "/");
                    compareMap.put(KEY_B_NUMBER, "<img src='"+protocol+"://"+rmiHost+"/"+webappName+"/netmarkets/images/doc_document.gif'/>" + docB.getNumber());
                    compareMap.put(KEY_B_NAME, docB.getName());
                    compareMap.put(KEY_B_VERSION, 
                            docB.getVersionIdentifier().getValue() 
                            + "." + docB.getIterationIdentifier().getValue());
                    
                    compareMap.put(KEY_COMPARE_RESULT, RESULT_ADD);
                    
                    resultList.add(compareMap);
                    index++;
                }
            }
            
            break;
        }
        
        LOGGER.debug("> End getCompareResultMap");
        return resultList;
    }
}
